import { OnInit, Component, Output, EventEmitter, ViewChild } from '@angular/core';
import { ProfessionDTO } from 'src/app/project/model/icm/icm-base/profession/profession.dto';
import { OperationNotification, OperationType } from 'src/app/project/model/common/operation-notification';
import { NgForm, FormGroup, FormBuilder, Validators, FormControl, ValidationErrors } from '@angular/forms';
import { GraduationCreditRequirementsDTO } from 'src/app/project/model/icm/icm-base/profession/graduationCreditRequirement.dto';
import { NzMessageService } from 'ng-zorro-antd';
import { ProfessionService } from 'src/app/project/service/icm/icm-base/profession/profession.service';
import { FormUtil } from '@shared/utils/form-util';
import { Observer, Observable } from 'rxjs';

@Component({
  selector: 'app-profession-detail',
  templateUrl: './profession-detail.component.html',
  styles: [],
})
export class ProfessionDetailComponent implements OnInit {
  constructor(private msg: NzMessageService, private professionService: ProfessionService, private fb: FormBuilder) {
    this.validateForm = this.fb.group({
      code: ['', [Validators.required], [this.codeAsyncValidator]],
      name: ['', [Validators.required, Validators.pattern('[^ ]+')]],
      shortName: [''],
      showOrder: ['', [Validators.required]],
      compulsoryCredit: ['', [Validators.required]],
      subjectBasedElective: ['', [Validators.required]],
      professionElective: ['', [Validators.required]],
      publicElective: ['', [Validators.required]],
      practiceCredit: ['', [Validators.required]],
      innovationScore: ['', [Validators.required]],
      graduationInternship: ['', [Validators.required]],
      graduationThesis: ['', [Validators.required]],
      total: ['', [Validators.required]],
    });
  }

  /**
   * 数据变化通知事件
   */
  @Output()
  notification = new EventEmitter<OperationNotification<ProfessionDTO>>();

  /**
   * form组件
   */
  @ViewChild('professionForm', { static: false })
  public professionForm: NgForm;

  /**
   * 表单
   */
  validateForm: FormGroup;

  /**
   * 是否预览
   */
  isPreView = false;

  /**
   * 表单窗体打开/关闭控制
   */
  isVisible = false;

  /**
   * 调用后台API标志
   */
  loading = false;

  /**
   * 专业的毕业学分最低要求
   */
  graduationCreditRequirements: GraduationCreditRequirementsDTO = {
    id: null,
    compulsoryCredit: 0,
    subjectBasedElective: 0,
    professionElective: 0,
    publicElective: 0,
    practiceCredit: 0,
    innovationScore: 0,
    graduationInternship: 0,
    graduationThesis: 0,
    total: 0,
  };

  /**
   * 专业信息
   */
  profession: ProfessionDTO = {
    id: null,
    code: '',
    name: '',
    showOrder: 0,
    graduationCreditRequirements: this.graduationCreditRequirements,
    academyId: null,
    academyName: null,
  };

  /**
   * 专业编码是否已存在，true为已存在
   */
  isExist: boolean;

  /**
   * 校验专业编码
   */
  codeAsyncValidator = (control: FormControl) =>
    new Observable((observer: Observer<ValidationErrors | null>) => {
      setTimeout(() => {
        if (control.value) {
          this.professionService.checkoutCodeIsExist(control.value).subscribe(data => {
            this.isExist = data.data;
          });
        }
        if (this.isExist) {
          observer.next({ error: true, duplicated: true });
        } else if (control.value.includes(' ')) {
          observer.next({ error: true, blank: true });
        } else {
          observer.next(null);
        }
        observer.complete();
      }, 1000);
    });

  /**
   * 计算合计学分
   */
  getTotal() {
    this.profession.graduationCreditRequirements.total =
      this.profession.graduationCreditRequirements.compulsoryCredit +
      this.profession.graduationCreditRequirements.graduationInternship +
      this.profession.graduationCreditRequirements.graduationThesis +
      this.profession.graduationCreditRequirements.innovationScore +
      this.profession.graduationCreditRequirements.practiceCredit +
      this.profession.graduationCreditRequirements.professionElective +
      this.profession.graduationCreditRequirements.publicElective +
      this.profession.graduationCreditRequirements.subjectBasedElective;
  }

  /**
   * 修改窗口状态
   */
  handleCancel() {
    this.isVisible = false;
    FormUtil.resetForm(this.professionForm.form);
  }

  /**
   * 修改或新增学院信息
   * @param isPreView 是否预览
   * @param item 学院信息
   */
  edit(isPreView: boolean, item: ProfessionDTO) {
    this.isPreView = isPreView;

    this.profession = this.initProfession(item);
    this.isVisible = true;
  }

  /**
   * 初始化专业
   */
  initProfession(item: ProfessionDTO): ProfessionDTO {
    return {
      id: item ? item.id : null,
      name: item ? item.name : '',
      code: item ? item.code : '',
      showOrder: item ? item.showOrder : 0,
      shortName: item ? item.shortName : '',
      graduationCreditRequirements: item ? item.graduationCreditRequirements : this.graduationCreditRequirements,
      academyId: item ? item.academyId : null,
      academyName: item ? item.academyName : null,
    };
  }

  /**
   * 保存前验证数据
   */
  beforeSave() {
    if (!this.profession.academyId) {
      this.msg.error('所属学院必选');
      return false;
    }
    if (this.profession.code === '') {
      this.msg.error('专业编码必填');
      return false;
    }
    if (this.profession.name === '') {
      this.msg.error('专业名称必填');
      return false;
    }
    if (!this.profession.showOrder && this.profession.showOrder !== 0) {
      this.msg.error('显示顺序必填');
      return false;
    }
    if (
      !this.profession.graduationCreditRequirements.compulsoryCredit &&
      this.graduationCreditRequirements.compulsoryCredit !== 0
    ) {
      this.msg.error('必修学分必填');
      return false;
    }
    if (
      !this.profession.graduationCreditRequirements.subjectBasedElective &&
      this.graduationCreditRequirements.subjectBasedElective !== 0
    ) {
      this.msg.error('学科基础选修必填');
      return false;
    }
    if (
      !this.profession.graduationCreditRequirements.professionElective &&
      this.graduationCreditRequirements.professionElective !== 0
    ) {
      this.msg.error('专业选修必填');
      return false;
    }
    if (
      !this.profession.graduationCreditRequirements.publicElective &&
      this.graduationCreditRequirements.publicElective !== 0
    ) {
      this.msg.error('公共选修必填');
      return false;
    }
    if (
      !this.profession.graduationCreditRequirements.practiceCredit &&
      this.graduationCreditRequirements.practiceCredit !== 0
    ) {
      this.msg.error('实践学分必填');
      return false;
    }
    if (
      !this.profession.graduationCreditRequirements.innovationScore &&
      this.graduationCreditRequirements.innovationScore !== 0
    ) {
      this.msg.error('创新分必填');
      return false;
    }
    if (
      !this.profession.graduationCreditRequirements.graduationInternship &&
      this.graduationCreditRequirements.graduationInternship !== 0
    ) {
      this.msg.error('毕业实习必填');
      return false;
    }
    if (
      !this.profession.graduationCreditRequirements.graduationThesis &&
      this.graduationCreditRequirements.graduationThesis !== 0
    ) {
      this.msg.error('毕业论文必填');
      return false;
    }
    return true;
  }

  /**
   * 保存
   */
  save() {
    if (!this.beforeSave()) {
      return;
    }
    this.loading = true;
    if (!this.profession.id) {
      // id为空，为新建
      this.professionService.create(this.profession).subscribe(
        data => this.afterItemSaved(data, OperationType.CREATE),
        () => this.msg.error('保存失败，请重试'),
        () => this.afterCallCompleted(),
      );
    } else {
      // id不为空，为修改
      this.professionService.complete(this.profession.id, this.profession).subscribe(
        data => this.afterItemSaved(data, OperationType.CREATE),
        () => this.msg.error('修改失败，请重试'),
        () => this.afterCallCompleted(),
      );
    }
  }

  /**
   * 数据保存后的通用操作
   *
   * @param data 保存的数据
   * @param operation 操作类型
   */
  private afterItemSaved(data: ProfessionDTO, operation: OperationType): void {
    this.loading = false;
    this.handleCancel();
    this.notification.emit({
      operation,
      data,
    });
    this.msg.success('保存成功!');
  }

  /**
   * API调用完成后的操作
   */
  private afterCallCompleted(): void {
    this.loading = false;
  }
  ngOnInit() {}
}
